<?php

declare(strict_types=1);

namespace Api\Middleware;

use Hyperf\Context\Context;
use Mine\Log\RequestIdHolder;
use Mine\MineRequest;
use PhpOffice\PhpSpreadsheet\Writer\Exception;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Xmo\JWTAuth\Util\JWTUtil;

class ColaAuthMiddleware implements MiddlewareInterface
{
    /**
     * 验证权限.
     * @throws Exception
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {

        //处理token
        $token = $request->getHeader('Authorization')[0] ?? null;
        $token = JWTUtil::handleToken($token);
        if (!$token) {
            return $this->responseError('请传入token', 403);
        }

        try {
            if (!colaUser()->check($token)) {
                return $this->responseError('Token 验证失败，可能已过期或者在黑名单', 403);
            }
        } catch (\Exception $e) {
            return $this->responseError($e->getMessage(), 403);
        }

        // 将token数据存储在请求属性中，以便后续使用
//        $request = $request->withAttribute('tokenData', colaUser()->getUserInfo($token));
//
//        $userInfo = colaUser()->getUserInfo($token);
//        // 使用协程上下文存储用户信息
//        Context::set('userInfo', $userInfo);

        return $handler->handle($request);
    }

    /**
     * 返回错误信息
     * */
    protected function responseError($message, $code)
    {
        $format = [
            'requestId' => RequestIdHolder::getId(),
            'path' => container()->get(MineRequest::class)->getUri()->getPath(),
            'success' => false,
            'message' => $message,
            'code' => $code,
            'data' => [],
        ];
        return container()->get(\Hyperf\HttpServer\Contract\ResponseInterface::class)->json($format);
    }


}
